package ch.wsl.postgres2mapperdao

/**
 * 
 * Postgres2mapperdao
 * 
 * @author Andrea Minetti
 *
 * 21 Sep 2012
 * 
 */

import ch.wsl.postgres2mapperdao.model.Table

object MapperDaoComposer {
  
  private def camelize(str: String): String = {
    val cc = str.split("_").map( t =>  t.capitalize ).mkString
	    if(str.endsWith("_"))
	      cc+"_"
	    else
	      cc
  }
  
  def compose(table: Table, withPackage: String): String = {

    
    var result = 	
      				"package " + withPackage + "\n" +
					"\n" +
					"\n" +
					"/** \n" +
					" * Generated by postgres2mapperdao\n" +
					" * from table "+table.table_schema+"."+table.table_name+"\n" +
					" */" +
					"\n" +
					"\n" +
					"\n" +
					"import org.scala_tools.time.Imports._\n" +
					"import com.googlecode.mapperdao.utils._\n" +
					"import com.googlecode.mapperdao._\n" +
					"\n" +
					"\n" +
					"class "+table.table_class+" (\n"
	
	for (field <- table.pure_fields) {
	  
		result = result +
					"       val "+field.column_name+": " + { if(field.nullable) "Option["+ field.field_type +"]" else field.field_type } + ",\n"
	  
	}
    
    for(fk <- table.foreignKeys) {
    	result = result +
    				"       val "+fk.table_name_external+{
    					if(!fk.nonNullable)
    						": Option["+ camelize(fk.refExtColumns.first.table_name) +"],\n"
    					else
    						": "+ camelize(fk.refExtColumns.first.table_name) +",\n"
    				}
    }
    
    result = result.substring(0,result.length()-2) //eliminate last "," and \n
    
	result = result +
					"\n) extends Id {\n" +
					"  \n" +
					"  override def mapperdao_id = List("
	
	
	if(!table.primaryKeys.isEmpty) {
	  
		for(pk <- table.primaryKeys.get){
		  
		  result = result + pk.column_name + ","
		  
		}
		
		result = result.substring(0,result.length()-1) //eliminate last ","
		
	}
	
    result = result +
					")\n" +
					"  \n" +
					"}\n" +
					"\n" +
					"\n" +
					"class "+table.table_class+"Dao(val mapperDao: MapperDao, val queryDao: QueryDao) extends MyCRUD["+table.table_class+", Int] with SimpleAll["+table.table_class+"] {\n" +
					"       import queryDao._\n" +
					"       \n" +
					"       val entity = "+table.table_class+"Entity\n" +
					"}\n" +
					"\n" +
					"\n" +
					"object "+table.table_class+"Entity extends SimpleEntity["+table.table_class+"](\""+table.table_schema+"."+table.table_name+"\", classOf["+table.table_class+"]) {\n" +
					"       \n"
					
					
	for (field <- table.pure_fields) {
	  
		result = result +
					"       val "+field.column_name+" = " + 
							{ if(table.hasKey(field.column_name)) " key" else " column" } + "(\""+field.column_name+"\")" +
							{ if(field.nullable) " option " else " to " } + "(_."+field.column_name+")" + "\n"
	  
	}
    
    for(fk <- table.foreignKeys) {
    	result = result +
    				"       val "+fk.table_name_external+" = " + 
    						"manytoone(" + camelize(fk.refExtColumns.first.table_name) + "Entity) " +
							"foreignkeys(List(" + {
    							var s = ""
    							for(fkc <- fk.refColumns.toList.sortWith((c1,c2) => (c1.column_name compareTo c2.column_name) < 0))
    							  s = s + "\""+fkc.column_name+"\"," 
    							s.substring(0,s.length()-1)
    						} +"))" +
    						{if(fk.nonNullable) " to " else " option "} +		//if the foreignkey has only non nullables element
    						" (_."+fk.table_name_external+")" + "\n"
    }
	
    
    result = result +
					"               \n" +
					"       def constructor(implicit m:ValuesMap) = new "+table.table_class+"(" + 
					{
    					var r = ""
    					for (field <- table.pure_fields) 
    						r = r + field.column_name + ","
    						
    					for(fk <- table.foreignKeys) 
    						r = r + fk.table_name_external + ","
    					
    					r.substring(0,r.length()-1)
					} + 
					") with Persisted\n" +
					"\n" +
					"}"
	
	result
    
  }
}